package com.jaiky.imagespickers;

import com.jaiky.imagespickers.container.SimpleImageAdapter;
import com.jaiky.imagespickers.utils.Options;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ListContainer;
import ohos.agp.components.TableLayoutManager;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.bundle.AbilityInfo;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * ================================================
 * 作    者：jeasonlzy（廖子尧 Github地址：https://github.com/jeasonlzy0216
 * 版    本：1.0
 * 创建日期：2016/5/19
 * 描    述：图片选择的入口类
 * 修订历史：
 * 2017-03-20
 *
 * @author nanchen
 * 采用单例和弱引用解决Intent传值限制导致的异常
 * ================================================
 */
public class ImagePicker {
    public static final int REQUEST_CODE_TAKE = 1001;
    public static final int REQUEST_CODE_PREVIEW = 1003;
    public static final int RESULT_CODE_ITEMS = 1004;
    public static final int RESULT_OK = 1001;
    public static final String EXTRA_RESULT_ITEMS = "extra_result_items";
    public static final String EXTRA_SELECTED_IMAGE_POSITION = "selected_image_position";
    public static final String EXTRA_IMAGE_ITEMS = "extra_image_items";
    public static final String EXTRA_FROM_ITEMS = "extra_from_items";
    private boolean multiMode = true;    // 图片选择模式
    private int selectLimit = 9;         // 最大选择图片数量
    private boolean crop = true;         // 裁剪
    private boolean showCamera = true;   // 显示相机
    private boolean isSaveRectangle = false;  // 裁剪后的图片是否是矩形，否者跟随裁剪框的形状
    private int outPutX = 800;           // 裁剪保存宽度
    private int outPutY = 800;           // 裁剪保存高度
    private int focusWidth = 280;         // 焦点框的宽度
    private int focusHeight = 280;        // 焦点框的高度
    private ImageLoader imageLoader;     // 图片加载器
    private File cropCacheFolder;
    public File takeImageFile;
    private ArrayList<ImageItem> mSelectedImages = new ArrayList<>();   // 选中的图片集合
    private List<ImageFolder> mImageFolders;      // 所有的图片文件夹
    private int mCurrentImageFolderPosition = 0;  // 当前选中的文件夹位置 0表示所有图片
    private List<OnImageSelectedListener> mImageSelectedListeners;          // 图片选中的监听回调
    private static Class takePhotoAbilityClass;
    private SimpleImageAdapter containerAdapter;
    private static ImagePicker mInstance = new ImagePicker();

    private ImagePicker() {
    }

    public static ImagePicker getInstance() {
        return mInstance;
    }

    public static void setTakePhotoAbility(Class clz) {
        takePhotoAbilityClass = clz;
    }

    public boolean isMultiMode() {
        return multiMode;
    }

    public void setMultiMode(boolean multiMode) {
        this.multiMode = multiMode;
    }

    public int getSelectLimit() {
        return selectLimit;
    }

    public void setSelectLimit(int selectLimit) {
        this.selectLimit = selectLimit;
    }

    public boolean isCrop() {
        return crop;
    }

    public void setCrop(boolean crop) {
        this.crop = crop;
    }

    public boolean isShowCamera() {
        return showCamera;
    }

    public void setContainer(ComponentContainer container, int rowImageCount, boolean isDelete) {
        if (container.getChildCount() == 0) {
            // 新建一个GridView
            ListContainer gvView = new ListContainer(container.getContext());
            ComponentContainer.LayoutConfig layoutParams = new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
                    ComponentContainer.LayoutConfig.MATCH_CONTENT);
            gvView.setLayoutConfig(layoutParams);
            TableLayoutManager tableLayoutManager = new TableLayoutManager();
            tableLayoutManager.setColumnCount(4);
            gvView.setLayoutManager(tableLayoutManager);

            // 设置适配器，暂时数据为控
            containerAdapter = new SimpleImageAdapter(container.getContext(), isDelete, rowImageCount);
            gvView.setItemProvider(containerAdapter);
            container.addComponent(gvView);
        } else {
            ListContainer gvView = (ListContainer) container.getComponentAt(0);
            containerAdapter = (SimpleImageAdapter) gvView.getItemProvider();
        }
    }

    /**
     * 获取容器适配器
     *
     * @return containerAdapter
     */
    public SimpleImageAdapter getContainerAdapter() {
        return containerAdapter;
    }

    /**
     * setShowCamera
     *
     * @param showCamera showCamera
     */
    public void setShowCamera(boolean showCamera) {
        this.showCamera = showCamera;
    }

    /**
     * isSaveRectangle
     *
     * @return isSaveRectangle
     */
    public boolean isSaveRectangle() {
        return isSaveRectangle;
    }

    /**
     * isSaveRectangle
     *
     * @param isSaveRectangle isSaveRectangle
     */
    public void setSaveRectangle(boolean isSaveRectangle) {
        this.isSaveRectangle = isSaveRectangle;
    }

    /**
     * getOutPutX
     *
     * @return outPutX
     */
    public int getOutPutX() {
        return outPutX;
    }

    /**
     * setOutPutX
     *
     * @param outPutX outPutX
     */
    public void setOutPutX(int outPutX) {
        this.outPutX = outPutX;
    }

    /**
     * getOutPutY
     * @return outPutY
     */
    public int getOutPutY() {
        return outPutY;
    }

    /**
     * setOutPutY
     *
     * @param outPutY outPutY
     */
    public void setOutPutY(int outPutY) {
        this.outPutY = outPutY;
    }

    /**
     * getFocusWidth
     *
     * @return focusWidth
     */
    public int getFocusWidth() {
        return focusWidth;
    }

    /**
     * setFocusWidth
     *
     * @param focusWidth focusWidth
     */
    public void setFocusWidth(int focusWidth) {
        this.focusWidth = focusWidth;
    }

    /**
     * getFocusHeight
     *
     * @return focusHeight
     */
    public int getFocusHeight() {
        return focusHeight;
    }

    /**
     * setFocusHeight
     * @param focusHeight focusHeight
     */
    public void setFocusHeight(int focusHeight) {
        this.focusHeight = focusHeight;
    }

    /**
     * getTakeImageFile
     *
     * @return takeImageFile
     */
    public File getTakeImageFile() {
        return takeImageFile;
    }

    /**
     * getCropCacheFolder
     *
     * @param context context
     * @return cropCacheFolder
     */
    public File getCropCacheFolder(Context context) {
        if (cropCacheFolder == null) {
            cropCacheFolder = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/ImagePicker/cropTemp/");
        }
        return cropCacheFolder;
    }

    /**
     * getImageLoader
     *
     * @return imageLoader
     */
    public ImageLoader getImageLoader() {
        return imageLoader;
    }

    /**
     * setImageLoader
     *
     * @param imageLoader imageLoader
     */
    public void setImageLoader(ImageLoader imageLoader) {
        this.imageLoader = imageLoader;
    }

    /**
     * setImageFolders
     *
     * @param imageFolders mImageFolders
     */
    public void setImageFolders(List<ImageFolder> imageFolders) {
        mImageFolders = imageFolders;
    }

    /**
     * setCurrentImageFolderPosition
     *
     * @param mCurrentSelectedImageSetPosition Position
     */
    public void setCurrentImageFolderPosition(int mCurrentSelectedImageSetPosition) {
        mCurrentImageFolderPosition = mCurrentSelectedImageSetPosition;
    }

    /**
     * getCurrentImageFolderItems
     *
     * @return images
     */
    public ArrayList<ImageItem> getCurrentImageFolderItems() {
        return mImageFolders.get(mCurrentImageFolderPosition).images;
    }

    /**
     * isSelect
     *
     * @param item ImageItem
     * @return  mSelectedImages.contains(item)
     */
    public boolean isSelect(ImageItem item) {
        return mSelectedImages.contains(item);
    }

    /**
     * getSelectImageCount
     *
     * @return mSelectedImages.size()
     */
    public int getSelectImageCount() {
        if (mSelectedImages == null) {
            return 0;
        }
        return mSelectedImages.size();
    }

    /**
     * getSelectedImages
     * @return mSelectedImages
     */
    public ArrayList<ImageItem> getSelectedImages() {
        return mSelectedImages;
    }

    /**
     * clearSelectedImages
     */
    public void clearSelectedImages() {
        if (mSelectedImages != null) {
            mSelectedImages.clear();
        }
    }

    /**
     * clear
     */
    public void clear() {
        if (mImageSelectedListeners != null) {
            mImageSelectedListeners.clear();
            mImageSelectedListeners = null;
        }
        if (mImageFolders != null) {
            mImageFolders.clear();
            mImageFolders = null;
        }
        if (mSelectedImages != null) {
            mSelectedImages.clear();
        }
        mCurrentImageFolderPosition = 0;
    }

    /**
     * 拍照的方法
     *
     * @param ability 上下文对象
     */
    public void takePicture(Context ability) {
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName(ability.getBundleName())
                .withAbilityName(takePhotoAbilityClass.getName())
                .build();
        Options options = Options.init()
                .setRequestCode(100)
                .setCount(5)
                .setFrontfacing(false)
                .setMode(Options.Mode.ALL)
                .setSpanCount(4)
                .setVideoDurationLimitinSeconds(10)
                .setScreenOrientation(AbilityInfo.DisplayOrientation.PORTRAIT)
                .setPath("pix/akshay");
        // 打开预览
        Intent itent = new Intent();
        itent.setOperation(operation);
        itent.setParam("options", options);
        ((Ability) ability).startAbilityForResult(itent, REQUEST_CODE_TAKE);
    }

    /**
     * 根据系统时间、前缀、后缀产生一个文件
     *
     * @param folder 文件夹
     * @param prefix prefix
     * @param suffix suffix
     * @return file
     */
    public static File createFile(File folder, String prefix, String suffix) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA);
        String filename = prefix + dateFormat.format(new Date(System.currentTimeMillis())) + suffix;
        return new File(folder, filename);
    }

    /**
     * 图片选中的监听
     */
    public interface OnImageSelectedListener {
        void onImageSelected(int position, ImageItem item, boolean isAdd);
    }

    /**
     * addOnImageSelectedListener
     *
     * @param ll OnImageSelectedListener
     */
    public void addOnImageSelectedListener(OnImageSelectedListener ll) {
        if (mImageSelectedListeners == null) {
            mImageSelectedListeners = new ArrayList<>();
        }
        mImageSelectedListeners.add(ll);
    }

    /**
     * removeOnImageSelectedListener
     *
     * @param ll OnImageSelectedListener
     */
    public void removeOnImageSelectedListener(OnImageSelectedListener ll) {
        if (mImageSelectedListeners == null) {
            return;
        }
        mImageSelectedListeners.remove(ll);
    }

    /**
     * addSelectedImageItem
     *
     * @param position position
     * @param item item
     * @param isAdd isAdd
     * @param type type
     */
    public void addSelectedImageItem(int position, ImageItem item, boolean isAdd, int type) {
        if (isAdd) {
            if (type != 0) {
                mSelectedImages.add(item);
            }
        } else {
            mSelectedImages.remove(item);
        }
        notifyImageSelectedChanged(position, item, isAdd);
    }

    /**
     * setSelectedImages
     *
     * @param selectedImages selectedImages
     */
    public void setSelectedImages(ArrayList<ImageItem> selectedImages) {
        if (selectedImages == null) {
            return;
        }
        this.mSelectedImages = selectedImages;
    }

    private void notifyImageSelectedChanged(int position, ImageItem item, boolean isAdd) {
        if (mImageSelectedListeners == null) {
            return;
        }
        for (OnImageSelectedListener ll : mImageSelectedListeners) {
            ll.onImageSelected(position, item, isAdd);
        }
    }

}